package com.example.origin.demo.demo.blockqueue;

import lombok.SneakyThrows;

import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Storage2 {

    private final int maxSize = 20;
    private LinkedList<Object> list = new LinkedList<Object>();
    private final Lock lock = new ReentrantLock();

    // 仓库满的条件变量
    private final Condition full = lock.newCondition();

    // 仓库空的条件变量
    private final Condition empty = lock.newCondition();

    @SneakyThrows
    public void put(Object obj) {
        lock.lock();

        while (list.size() >= maxSize) {
            System.out.println("缓冲区已满，不能进入");
            // 生产阻塞
            full.await();
        }

        list.add(obj);
        System.out.println("进入缓冲区");
        empty.signalAll();

        lock.unlock();
    }

    @SneakyThrows
    public Object get() {
        lock.lock();

        while (list.size() <= 0) {
            System.out.println("缓冲区为空, 进入等待");
            // 消费阻塞
            empty.await();
        }

        Object obj = list.remove();
        System.out.println("离开缓冲区");
        full.signalAll();

        lock.unlock();

        return obj;
    }

    public static void main(String[] args) throws InterruptedException {
        Storage2 storage1 = new Storage2();
        new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            storage1.get();
        }).start();

        for (int i = 0; i < 11; i++) {
            storage1.put(Integer.valueOf(1));
        }
    }

}